package com.ZeroCarbon.interceptors;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.ZeroCarbon.utils.GatewayIpUtils;
import com.ZeroCarbon.utils.JwtTool;
import com.ZeroCarbon.utils.UserHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.ZeroCarbon.prefix.RedisKey.LOGIN;

/**
 * 用户信息拦截器
 *
 * @since 2024-10-16
 */
@Component
@RequiredArgsConstructor
public class UserInfoInterceptor implements HandlerInterceptor {

    private final StringRedisTemplate redis;

    private final JwtTool jwtTool;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 获取用户的userId
        String userId = request.getHeader("userId");

        if (userId == null) {
            // 防止有些页面不需要验证就能访问，但同时需要userId的，所以需要判断是否登录
            String userIdFromToken = null;
            // 抛出异常说明没有登录，继续执行
            try {
                // 获取Access Token
                String token = request.getHeader("Authorization");
                // 获取User-Agent
                String header = request.getHeader("User-Agent");
                // 校验
                userIdFromToken = jwtTool.parseAccessToken(token, GatewayIpUtils.getClientIp(request), header);
            } catch (Exception e) {

            }
            // 判断是否登录
            Boolean isLogin = null;
            // 如果第二次解析还是没有，说明是游客身份登录的
            if (userIdFromToken != null) {
                // 从redis查看客户登录状态
                isLogin = redis.hasKey(LOGIN + userIdFromToken);
            }
            // 如果redis中含有数据并且未过期，说明用户登录了
            if (BooleanUtil.isTrue(isLogin)) {
                userId = userIdFromToken;
            }
        }

        // 设置用户id
        if (StrUtil.isNotBlank(userId)) {
            UserHolder.setUser(userId);
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserHolder.removeUser();
    }
}
